import cn from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { useForm } from 'react-hook-form';
import { Link } from 'react-router-dom';
import { Warning32 as Warning } from '@carbon/icons-react';
import { gql, useQuery, useMutation } from '@apollo/client';
import Helper from '../../../../components/Helper';
import Joi from 'joi';
import { joiResolver } from '@hookform/resolvers';
import Table from '@knownsec/react-component/dist/Table';
import CopyBoard from '../../../../components/CopyBoard';
import Tooltip from '@kuiper-components/tooltip';

import { withRouter } from 'react-router';

import Dialog from '@kuiper-components/dialog';
import Input from '@kuiper-components/input';
import Button from '@kuiper-components/button';
import notification from '@kuiper-components/notification';
import Form, { Field } from '../../../../components/Form';
import URLTextarea from '../../../../components/AdvanceSettings/URLTextarea';
import s from './style.module.css';
import moment from 'moment';

const USER_QUERY = gql`
	query {
		UserOne {
			_id
			disclaimerAgreeTime
		}
	}
`;

const AGREE_DISCLAIMER = gql`
	mutation {
		UpdateAgreeTime {
			_id
			disclaimerAgreeTime
		}
	}
`;
const addCol = [
	{
		title: '资产类型',
		dataIndex: 'asset_type',
		key: 'asset_type',
	},
	{
		title: '资产名称',
		dataIndex: 'note',
		key: 'note',
		render(e) {
			return (
				<Tooltip trigger={['hover']} placement="top" overlay={e}>
					<span>{e}</span>
				</Tooltip>
			);
		},
	},
	{
		title: '失败原因',
		dataIndex: 'reason',
		key: 'reason',
		render(e) {
			return (
				<Tooltip trigger={['hover']} placement="top" overlay={e}>
					<span>{e}</span>
				</Tooltip>
			);
		},
	},
	{
		title: '资产地址',
		dataIndex: 'target_url',
		key: 'target_url',
		render(e) {
			return (
				<div className={s.ell} title={e}>
					<CopyBoard text={e} />
				</div>
			);
		},
	},
];
function CreateJob({
	className,
	children,
	onSubmit,
	location,
	maxDomain,
	userInfo,
	isDialog,
	record,
	refetch,
}) {
	const search = new URLSearchParams(location.search);
	const openAndCreate = search.get('create-job');
	const plan_name = JSON.parse(sessionStorage.resD).plan_name;
	const [loading, setLoading] = React.useState(false);
	const [isAgreed, setIsAgreed] = React.useState(false);
	const [addEnd, setAddEnd] = React.useState(false);
	const [targetUrlsChange, setTargetUrlsChange] = React.useState([]);
	const [createDialogVisible, setCreateDialogVisible] = React.useState(
		!!openAndCreate
	);
	const [agreeVisible, setAgreeVisible] = React.useState(false);
	const isPlanTimeOut =
		moment().unix() > moment(sessionStorage.planTimeOut).unix();

	const hosJob = joiResolver(
		Joi.object({
			note: Joi.string()
				.required()
				.regex(/^[a-zA-Z0-9_\u4E00-\u9FA5]{1,50}$/)
				.trim()
				.messages({
					'any.required': '资产名称不能为空',
					'string.empty': '资产名称不能为空',
					'string.pattern.base':
						'名称格式错误，只能输入1～50个中文、英文字母、数字、下划线',
				}),
			target_urls: Joi.array()
				.items(Joi.string())
				.min(1)
				.max(100)
				.required()
				.messages({
					'any.required': '资产地址不能为空',
					'array.min': '资产地址不能为空',
					'array.max': '最多添加100个资产',
				}),
		})
	);
	const hosJob2 = joiResolver(
		Joi.object({
			note: Joi.string()
				.regex(/^[a-zA-Z0-9_\u4E00-\u9FA5]{1,50}$/)
				.required()
				.messages({
					'any.required': '资产名称不能为空',
					'string.empty': '资产名称不能为空',
					'string.pattern.base':
						'名称格式错误，只能输入1～50个中文、英文字母、数字、下划线',
				}),
			target_url: Joi.string().empty(null, '').allow('').trim(),
		})
	);
	const form = useForm({
		defaultValues: {
			target_url: record?.target_url || [],
			target_urls: record?.target_url || [],
			note: record?.note || '',
		},
		mode: 'onBlur',
		resolver: record?.target_url ? hosJob2 : hosJob,
	});
	const [updateAgreeDate] = useMutation(AGREE_DISCLAIMER);
	const { data } = useQuery(USER_QUERY, {
		variables: { uid: userInfo?.uid },
	});
	const handleCloseModal = () => {
		setCreateDialogVisible(false);
		!record && refetch();
	};

	const handleCloseAgreeModal = () => setAgreeVisible(false);

	const handleChildrenClick = () => {
		if (!userInfo?.identified) {
			notification.error({
				message: '当前还未进行实名认证，无法添加资产。',
				placement: 'top',
				style: { width: '22rem' },
			});
			return;
		}
		if (isPlanTimeOut) {
			notification.error({
				message: '当前套餐已过期，无法添加资产',
				placement: 'top',
			});
			return;
		}
		if (plan_name === '免费版') {
			notification.error({
				message: '当前账号未开通套餐',
				placement: 'top',
			});
			return;
		}
		if (maxDomain?.total - maxDomain?.used <= 0) {
			notification.error({
				message: '当前套餐资产数已达到上限，无法继续添加。',
				placement: 'top',
			});
			return;
		}
		if (!data?.UserOne?.disclaimerAgreeTime) {
			setAgreeVisible(true);
			return;
		} else {
			if (isDialog) {
				setCreateDialogVisible(true);
			}
		}
		const onClick = children.props.onClick;
		if (onClick) onClick();
	};

	const handleAgree = () => {
		updateAgreeDate()
			.then(() => {
				setAgreeVisible(false);
				if (isDialog) {
					setCreateDialogVisible(true);
				} else {
					const onClick = children.props.onClick;
					if (onClick) onClick();
				}
			})
			.catch(err => {
				notification.error({ message: err.message, placement: 'top' });
			});
	};

	const handleAgreeChange = val => {
		setIsAgreed(val);
	};

	const handleSubmit = async data => {
		if (record) {
			data.jobId = record.job_id;
		}
		setLoading(true);
		if (loading) return;
		const resp = await onSubmit(data);
		setLoading(false);
		if (resp.code === 0 || resp.message === '修改成功') {
			setCreateDialogVisible(false);
		} else {
			if (resp.code === 403) {
				notification.error({
					message: resp.msg,
					placement: 'top',
					style: { width: '22rem' },
				});
				return false;
			}
			const res = JSON.parse(JSON.stringify(resp.data));
			form.setValue(
				'target_url',
				res.detail.map(item => {
					return item.target_url;
				})
			);
			form.setValue(
				'target_urls',
				res.detail.map(item => {
					return item.target_url;
				})
			);
			setTargetUrlsChange(res);
			setAddEnd(res);
		}
	};
	React.useEffect(() => {
		if (createDialogVisible && record) {
			setTimeout(() => {
				form.setValue('note', record.note);
			}, 0);
		}
	}, [createDialogVisible]);
	return (
		<>
			{React.cloneElement(children, {
				...children.props,
				onClick: handleChildrenClick,
			})}
			<Dialog
				title="提示"
				visible={agreeVisible}
				wrapClassName={s.dialog}
				onClose={handleCloseAgreeModal}
				destroyOnClose={true}
			>
				<div className={s.agreeWapper}>
					<Warning className={s.warningIcon} />
					<div className={s.text}>
						<span>在添加资产前，请确认您已仔细阅读并同意</span> <br />
						<div>
							<Input
								type="checkbox"
								checked={isAgreed}
								onChange={handleAgreeChange}
							/>
							<Link to="/disclaimer" target="_blank">
								《知道创宇ScanV服务条款》
							</Link>
						</div>
					</div>
					<span>
						<Button className={s.quit} onClick={handleCloseAgreeModal}>
							取消
						</Button>
						{!isAgreed ? (
							<Button disabled={true}>已阅读并同意</Button>
						) : (
							<Button primary onClick={handleAgree}>
								已阅读并同意
							</Button>
						)}
					</span>
				</div>
			</Dialog>
			<Dialog
				title={record ? '修改资产' : '添加资产'}
				visible={createDialogVisible}
				wrapClassName={s.dialog}
				onClose={handleCloseModal}
				destroyOnClose={true}
				className={s.addDomain}
			>
				<>
					<Form
						className={cn(className, s.createJob)}
						form={form}
						onSubmit={handleSubmit}
					>
						<div className={s.inputContainer}>
							<Field
								required
								className={s.formField}
								label="资产名称"
								name="note"
								as={Input}
								placeholder="请输入资产名称"
								componentClassName={s.input}
							/>
							{record ? (
								<Field
									required
									className={s.formField}
									label="资产地址"
									name="target_url"
									as={Input}
									placeholder="请输入资产地址"
									componentClassName={s.input}
									disabled={true}
								/>
							) : (
								<Field
									required
									label="资产地址"
									name="target_urls"
									className={s.formField}
									render={({ onChange, onBlur, value }) => {
										return (
											<div className={s.urlTextareaWrapper}>
												<URLTextarea
													key={targetUrlsChange}
													className={s.textarea}
													placeholder="请输入主机资产地址，若有多个IP地址可换行添加"
													onChange={onChange}
													onBlur={onBlur}
													value={value}
													asType={'host'}
												/>
												<Helper
													placement="top"
													overlay={
														<div style={{ maxWidth: '20rem' }}>
															<div>支持添加IPv4地址，示例：1.1.1.1</div>
															<div>
																最大可添加100条，更多资产建议使批量导入功能
															</div>
														</div>
													}
												/>
											</div>
										);
									}}
								/>
							)}
							<div className={s.warningTips}>
								注：资产认证后，系统默认一周一次监测频率探测资产信息。
							</div>
						</div>
						<div className={s.btnContainer}>
							<Button className={s.btn} size="small" onClick={handleCloseModal}>
								取消
							</Button>
							<Button
								className={s.btn}
								primary
								size="small"
								type="submit"
								loading={loading}
							>
								{record ? '修改' : '添加'}
							</Button>
						</div>
					</Form>
					<Dialog
						title="添加资产失败"
						visible={addEnd}
						wrapClassName={s.dialog}
						onClose={() => {
							setAddEnd(false);
						}}
						destroyOnClose={true}
						className={s.addDomain}
					>
						<div>
							<p>
								<span>总计：{addEnd.summary?.total}</span>
								<span className={s.ml20}>成功：{addEnd.summary?.success}</span>
								<span className={s.ml20}>失败：{addEnd.summary?.fail}</span>
							</p>
						</div>
						<div className={s.table}>
							<Table columns={addCol} data={addEnd.detail} loading={false} />
						</div>
						<div className={cn(s.btnContainer, s.btnBox)}>
							<Button
								primary
								className={s.btn}
								size="small"
								onClick={() => {
									setAddEnd(false);
								}}
							>
								返回修改
							</Button>
							<Button
								className={s.btn}
								size="small"
								onClick={() => {
									setAddEnd(false);
									handleCloseModal();
								}}
							>
								确定
							</Button>
						</div>
					</Dialog>
				</>
			</Dialog>
		</>
	);
}

CreateJob.propTypes = {
	refetch: PropTypes.any,
	record: PropTypes.any,
	className: PropTypes.string,
	children: PropTypes.node.isRequired,
	onSubmit: PropTypes.func.isRequired,
	isDialog: PropTypes.bool,
	location: PropTypes.shape({
		search: PropTypes.string,
	}),
	maxDomain: PropTypes.any,
	userInfo: PropTypes.shape({
		identified: PropTypes.bool,
		uid: PropTypes.string,
	}),
};
CreateJob.defaultProps = {
	className: s.createJob,
};

export default withRouter(CreateJob);
